home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / S.N.A.G. Disk of the Month 91-03 (1991)(Southern Nevada Amiga Group)(PD).zip / S.N.A.G. Disk of the Month 91-03 (1991)(Southern Nevada Amiga Group)(PD).adf / PIV / do_req.c next >
C/C++ Source or Header  |  1991-03-29  |  4KB  |  208 lines

  1. /* do_req.c
  2.  *
  3.  * Manage the requester window for PIV.
  4.  *
  5.  * (c) Copyright 1991 J.E.Hanway
  6.  *
  7.  * $Id: do_req.c,v 1.1 91/03/13 22:32:41 jeh Exp $
  8.  *
  9.  * $Log:    do_req.c,v $
  10.  * Revision 1.1  91/03/13  22:32:41  jeh
  11.  * Initial revision
  12.  * 
  13.  */
  14.  
  15. #include <exec/types.h>
  16. #include <exec/memory.h>
  17. #include <intuition/intuition.h>
  18. #include <proto/exec.h>
  19. #include <proto/intuition.h>
  20. #include <proto/dos.h>
  21. #include <string.h>
  22. #include <stdarg.h>
  23.  
  24. #include "PIV.h"
  25.  
  26. /* Semaphore that is held whenever the code is in use
  27.  */
  28. struct SignalSemaphore inuse_sema;
  29.  
  30. /* use count
  31.  */
  32. struct SignalSemaphore usecount_sema;
  33. long   usecount = 0;
  34.  
  35. /* keep track of the previous operation for the "cancel once" feature
  36.  */
  37. static struct SignalSemaphore rc_sema;
  38. static char   lastvol[40] = "";
  39. static long   lastrc = -1L;
  40.  
  41. void
  42. init_semaphores(void)
  43. {
  44.     InitSemaphore(&inuse_sema);
  45.     InitSemaphore(&usecount_sema);
  46.     InitSemaphore(&rc_sema);
  47. }
  48.  
  49. static void
  50. free_context(context_t *ct)
  51. {
  52.    FreeMem(ct, sizeof(context_t));
  53. }
  54.  
  55. static context_t *
  56. get_context(void)
  57. {
  58.    int i;
  59.    
  60.    context_t *ct = AllocMem(sizeof(context_t), MEMF_CLEAR);
  61.    
  62.    if(ct) {
  63.       for(i = 0; i < 6; i++) {
  64.          ct->g[i] = *gproto[i];
  65.          ct->g[i].NextGadget = &ct->g[i+1];
  66.       }
  67.       ct->g[4].SpecialInfo = (APTR) &ct->si;
  68.       ct->g[5].GadgetText = &ct->it;
  69.       ct->g[5].NextGadget = NULL;
  70.       ct->si.Buffer = ct->strbuf;
  71.       ct->si.MaxChars = 80;
  72.       ct->nw = nw_proto;
  73.       ct->nw.FirstGadget = &ct->g[0];
  74.       ct->it = *vol_text;
  75.       ct->it.IText = ct->line;
  76.    }
  77.    
  78.    return ct;
  79. }
  80.  
  81. /* cat() concatenates strings together and avoids linking in a large
  82.  * implementation of sprintf.
  83.  *
  84.  * Usage: cat(s1, s2, s3, ..., NULL);
  85.  * (s1 had better have enough room!)
  86.  */
  87. static void
  88. cat(char *s, ...)
  89. {
  90.     char *s1;
  91.     va_list ap;
  92.    
  93.     va_start(ap, s);
  94.    
  95.     *s = '\0';
  96.    
  97.     while(s1 = va_arg(ap, char *)) {
  98.         strcat(s, s1);
  99.     }
  100.    
  101.     va_end(ap);
  102. }
  103.  
  104. long
  105. do_req(struct Window *client_win, char *volume)
  106. {
  107.     struct Window    *win;
  108.     struct IntuiMessage *msg;
  109.     extern BPTR    nilfh;
  110.     context_t    *ct;
  111.     long        rc = -1;    /* return code */
  112.  
  113.     /* bump the use count
  114.      */
  115.     ObtainSemaphore(&usecount_sema);
  116.     usecount++;
  117.  
  118.     /* If we're the first use, grab the inuse semaphore
  119.      */
  120.     if(1L == usecount)
  121.         ObtainSemaphore(&inuse_sema);
  122.     ReleaseSemaphore(&usecount_sema);
  123.     
  124.     /* If this requester is exactly the same as one which was just canceled,
  125.      * then don't bother displaying anything, just cancel it again.
  126.      * This gets around some programs that like to retry three times.
  127.      *
  128.      * Note that the string comparison is case sensitive, so if you
  129.      * accidentally cancel something you didn't mean to, you can force a
  130.      * requester to appear by fudging the case. 
  131.      */
  132.     ObtainSemaphore(&rc_sema);
  133.     if(lastrc == 0 && !strcmp(volume, lastvol)) {
  134.         ReleaseSemaphore(&rc_sema);
  135.         rc = 0;
  136.         goto done;
  137.     }
  138.          ReleaseSemaphore(&rc_sema);
  139.      
  140.     if(!(ct = get_context())) {
  141.         goto done;
  142.     }
  143.      
  144.     if(client_win) {
  145.         ct->nw.Screen = client_win->WScreen;
  146.         ct->nw.Type = CUSTOMSCREEN;
  147.     } else {
  148.         ct->nw.Screen = NULL;
  149.         ct->nw.Type = WBENCHSCREEN;
  150.     }
  151.    
  152.     cat(ct->line, "Volume ", volume, NULL);
  153.    
  154.     if(win = OpenWindow(&ct->nw)) {
  155.         (void) ActivateGadget(&ct->g[4], win, NULL);
  156.         while(rc == -1) {
  157.             Wait(1L << win->UserPort->mp_SigBit);
  158.             while(msg = (struct IntuiMessage *) GetMsg(win->UserPort)) {
  159.                 struct Gadget *gad = (struct Gadget *)(msg->IAddress);
  160.  
  161.                 ReplyMsg((struct Message *) msg);
  162.                 switch(gad->GadgetID) {
  163.                 case RETRY:
  164.                     rc = 1;
  165.                     break;
  166.                 case MOUNT:
  167.                     cat(ct->cmd, "mount ", volume, ":\n", NULL);
  168.                     (void) Execute(ct->cmd, nilfh, nilfh);
  169.                     rc = 1;
  170.                     break;
  171.                 case ASSIGN:
  172.                     cat(ct->cmd, "assign ", volume, ": ", ct->strbuf, "\n", NULL);
  173.                     (void) Execute(ct->cmd, nilfh, nilfh);
  174.                     rc = 1;
  175.                     break;     
  176.                 case CANCEL:
  177.                     rc = 0;
  178.                     break;
  179.                 }
  180.             }
  181.         }
  182.         CloseWindow(win);
  183.     } 
  184.  
  185.     free_context(ct);
  186.     
  187. done:
  188.     /* save the return code
  189.      */
  190.     ObtainSemaphore(&rc_sema);
  191.     lastrc = rc;
  192.     if(0 == rc)
  193.         strncpy(lastvol, volume, 40);
  194.     ReleaseSemaphore(&rc_sema);
  195.  
  196.     /* One less user
  197.      */
  198.     ObtainSemaphore(&usecount_sema);
  199.     usecount--;
  200.     /* If we're the last to leave, release the inuse semaphore
  201.      */
  202.     if(0L == usecount)
  203.         ReleaseSemaphore(&inuse_sema);
  204.     ReleaseSemaphore(&usecount_sema);
  205.  
  206.     return rc;  
  207. }
  208.